<template>
  <div class="TransformThreeD">
    <div class="left" @click="goNext(i-1)">《</div>
    <div class="container" :style="{'--width': this.width}">
      <div v-for="(item, index) in list" :key="index" class="piece" :style="`background-color: ${item?.color ?? 'unset'}`">
        <div class="label">{{ item?.label }}</div>
      </div>
    </div>
    <div class="right" @click="goNext(i+1)">》</div>
  </div>
</template>

<script>
export default {
  name: 'TransformThreeD',

  data() {
    return {
      list: [
        { label: 'test1' },
        { label: 'test2' },
        { label: 'test3' },
        { label: 'test4' },
        { label: 'test5' },
        { label: 'test6' },
        { label: 'test7' },
        { label: 'test8' },
      ],
      width: 200,
      i: 0,
    };
  },

  computed: {
    translateZ() {
      return (this.width / 2 / Math.tan(Math.PI / this.list.length)) + 'px'
    },
  },

  mounted() {
    let trueLength = this.list.length
    let list = this.list.map(item => ({...item, color: this.getRandomColorStr()}))
    this.list = [...list, ...list]
    this.$nextTick(() => {
      this.goNext((1-trueLength) / 2)
    })
  },

  methods: {
    goNext(target) {
      this.i = target
      this.$el.querySelectorAll('.piece').forEach((item, index) => {
        item.style.transform = `rotateY(${(index + this.i) * 360 / this.list.length}deg) translateZ(${this.translateZ})`
      })
    },
    getRandomColorStr() {
      return '#' + Math.random().toString(16).slice(2, 8).padEnd(6, 0)
    },
  },
};
</script>

<style lang="less" scoped>
.TransformThreeD ::v-deep {
  display: flex;
  flex-flow: row;
  align-items: stretch;
  height: 100%;
  width: 100%;
  background-color: #eee;
  perspective: 20000px;
  position: absolute;
  & > .container {
    position: relative;
    width: calc(var(--width) * 1px);
    height: 200px;
    margin: 300px auto;
    perspective-origin: 50% 50%;
    transform-style: preserve-3d;
    transform: rotateX(-18deg);
    transition: all 0.5s;
    & > .piece {
      backface-visibility: hidden;
      position: absolute;
      width: calc(var(--width) * 1px);
      height: 200px;
      opacity: .5;
      transition: all 0.5s;
      overflow: hidden;
      display: flex;
      align-content: center;
      justify-content: center;
      align-items: center;
      .label {
        position: absolute;
        color: #fff;
      }
    }
  }
  & > .left, & > .right {
    padding: 10px;
    display: flex;
    align-items: center;
    cursor: pointer;
    user-select: none;
    &:hover {
      background: #B0D7FF;
    }
  }
}
</style>